/******************************************************************************\


 * 
 * 
 * Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.               *
 * Leap Motion proprietary and confidential. Not for distribution.              *
 * Use subject to the terms of the Leap Motion SDK Agreement available at       *
 * https://developer.leapmotion.com/sdk_agreement, or another agreement         *
 * between Leap Motion and you, your company or other organization.             *
\******************************************************************************/

import java.io.IOException;
import java.lang.Math;
//now this line
import com.leapmotion.leap.*;
import com.leapmotion.leap.Gesture.State;

class SampleListener extends Listener {

//this should cause a conflict

	public static float scaleDistance1 = 1;
	public static float scaleDistance2 = 1;
	public static float scaleDistanceFinal = 1;
	

	public static float translateDistanceFinalX = 0;
	public static float translateDistanceFinalY = 0;
	public static float translateDistanceFinalZ = 0;

	public static boolean useLeap = false;
	public static boolean translateBoolean = false;
	
	public static int shapeActivated = 0;

	public static boolean deleteSelectedShape = false;
	public static boolean undoLastAction = false;
	public static boolean redoLastAction = false;
	public static boolean circleCheck = true;
	public static boolean circleCheckDelete = true;
	
	static Vector translationVector = new Vector(0, 0, 0);
	static Vector normalizedTranslationVector = new Vector(translationVector);

	
	// /////////// Leap Helper Functions ////////////////////////

	public static boolean getUseLeap() {
		return useLeap;
	}

	public static boolean getTranslateBoolean() {
		return translateBoolean;
	}

	public static void resetUseLeap() {
		useLeap = false;
	}

	public static float getScaleDistanceFinal() {
		return scaleDistanceFinal;
	}

	public void scaleDistanceReset() {
		scaleDistance1 = 1;
		scaleDistance2 = 1;
		scaleDistanceFinal = 1;
	}

	public static float getTranslateDistanceX() {
		return translateDistanceFinalX;
	}

	public static float getTranslateDistanceY() {
		return translateDistanceFinalY;
	}

	public static float getTranslateDistanceZ() {
		return translateDistanceFinalZ;
	}
	
	public static int getShapeActivation(){
		return shapeActivated;
	}

	// /////////// Leap Deterministic Functions ////////////////////////

	public void onInit(Controller controller) {
		System.out.println("Initialized");
	}

	public void onConnect(Controller controller) {
		System.out.println("Connected");
		controller.enableGesture(Gesture.Type.TYPE_SWIPE);
		controller.enableGesture(Gesture.Type.TYPE_CIRCLE);
		controller.enableGesture(Gesture.Type.TYPE_SCREEN_TAP);
		controller.enableGesture(Gesture.Type.TYPE_KEY_TAP);
	}

	public void onDisconnect(Controller controller) {
		// Note: not dispatched when running in a debugger.
		System.out.println("Disconnected");
	}

	public void onExit(Controller controller) {
		System.out.println("Exited");
	}

	public void onFrame(Controller controller) {
		// Get the most recent frame and report some basic information
		deleteSelectedShape = false;
		undoLastAction = false;
		redoLastAction = false;
		shapeActivated = 0;
		translateDistanceFinalX = 0;
		translateDistanceFinalY = 0;
		translateDistanceFinalZ = 0;
		translateBoolean = false;
		
		
		
		Frame frame = controller.frame();
		GestureList gestures = frame.gestures();
		Gesture gesture = gestures.get(0);
		
		
		
		if (!frame.hands().isEmpty()) {
			// Get the first hand
			Hand hand1 = frame.hands().get(0);
			Hand hand2 = frame.hands().get(1);

			// Check if the hand has any fingers
			FingerList fingersHand1 = hand1.fingers();
			FingerList fingersHand2 = hand2.fingers();
			
			//System.out.println("Hand1: " + fingersHand1.count() + " Hand2: " + fingersHand2.count());
			
			////////////////////////////////////////////////////////////////////////
			/////////////Scaling motion below
			//////////////////////////////////////////////////////////////////////////

			if (((fingersHand1.count() == 1) && (fingersHand2.count() == 1))) {
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 0;
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
				// Calculate the hand's average finger tip position
				if ((scaleDistance1 == 1) && (scaleDistance2 == 1)) {
					scaleDistance1 = Math.abs(((fingersHand1.get(0)
							.tipPosition().getX() * (-1)) + fingersHand2.get(0)
							.tipPosition().getX()) / 100);
				}

				else if ((scaleDistance1 != 1) && (scaleDistance2 == 1)) {
					scaleDistance2 = Math.abs(((fingersHand1.get(0)
							.tipPosition().getX() * (-1)) + fingersHand2.get(0)
							.tipPosition().getX()) / 100);
				}

				else if ((scaleDistance1 != 1) && (scaleDistance2 != 1)) {
					scaleDistanceFinal = scaleDistance1 - scaleDistance2;
					scaleDistance1 = 1;
					scaleDistance2 = 1;
					useLeap = true;
				}

				// System.out.println("scale1: " + scaleDistance1);
				// System.out.println("scale2: " + scaleDistance2);
				// System.out.println("Final: " + scaleDistanceFinal);
				deleteSelectedShape = false;
				Main.canvas.display();
				
				undoLastAction = false;
				redoLastAction = false;
				shapeActivated = 0;
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
				
				// System.out.println("Distance Scale: "+scaleDistance);
				
				///////////////////////////////////////////////////////////////////////////
				//////////////Translation Motion Below
				///////////////////////////////////////////////////////////////////////////

			} else if (((fingersHand1.count() == 2) && (fingersHand2.isEmpty())) || ((fingersHand2.count() == 2) && (fingersHand1.isEmpty()))) {
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 0;
				scaleDistanceReset();

				float finger1coordinateX = fingersHand1.get(0).tipPosition()
						.getX();
				float finger2coordinateX = fingersHand1.get(1).tipPosition()
						.getX();

				float finger1coordinateY = fingersHand1.get(0).tipPosition()
						.getY();
				float finger2coordinateY = fingersHand1.get(1).tipPosition()
						.getY();

				float finger1coordinateZ = fingersHand1.get(0).tipPosition()
						.getZ();
				float finger2coordinateZ = fingersHand1.get(1).tipPosition()
						.getZ();

				translateDistanceFinalX = ((finger1coordinateX + finger2coordinateX) / 2);
				translateDistanceFinalY = ((finger1coordinateY + finger2coordinateY) / 2);
				translateDistanceFinalZ = ((finger1coordinateZ + finger2coordinateZ) / 2);

				translationVector.setX(translateDistanceFinalX);
				translationVector.setY(translateDistanceFinalY);
				translationVector.setZ(translateDistanceFinalZ);

				InteractionBox interactionBox = frame.interactionBox();

				normalizedTranslationVector = interactionBox
						.normalizePoint(translationVector);
				translateBoolean = true;
				Main.canvas.display();
				
				deleteSelectedShape = false;
				undoLastAction = false;
				redoLastAction = false;
				shapeActivated = 0;
				scaleDistanceReset();
				// System.out.println(normalizedTranslationVector);

				/*
				 * System.out.println("xcoord: " + translationVector.getX() +
				 * " ycoord: " + translationVector.getY() + " zcoord: " +
				 * translationVector.getZ());
				 */

				// System.out.println("Xcoord " + translateDistanceFinalX);
				// System.out.println("Ycoord " + translateDistanceFinalY);
				// System.out.println("Zcoord " + translateDistanceFinalZ);

			}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Cube Shape Creation Below
			//////////////////////////////////////////////////////////////////////////////////////
			
			else if((gesture.type() == Gesture.Type.TYPE_KEY_TAP) && (((fingersHand1.count() == 1) && (fingersHand2.count() == 2)) || ((fingersHand1.count() == 2) && (fingersHand2.count() == 1)))){
				//KeyTapGesture cubeKeyTap = new KeyTapGesture(gesture);
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 2;
				System.out.println("Cube Recognized"+ shapeActivated);
				Main.canvas.display();
				shapeActivated = 0;
				scaleDistanceReset();
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
			}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Cylinder Shape Creation Below
			//////////////////////////////////////////////////////////////////////////////////////
			
			else if((gesture.type() == Gesture.Type.TYPE_KEY_TAP) && (((fingersHand1.count() == 1) && (fingersHand2.count() == 3)) || ((fingersHand1.count() == 3) && (fingersHand2.count() == 1)))){
//				KeyTapGesture cylinderKeyTap = new KeyTapGesture(gesture);
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 3;
				System.out.println("Cylinder Recognized");
				Main.canvas.display();
				shapeActivated = 0;
				scaleDistanceReset();
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
			}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Pyramid Shape Creation Below
			//////////////////////////////////////////////////////////////////////////////////////
			
			else if((gesture.type() == Gesture.Type.TYPE_KEY_TAP) && (((fingersHand1.count() == 1) && (fingersHand2.count() == 4)) || ((fingersHand1.count() == 4) && (fingersHand2.count() == 1)))){
//				KeyTapGesture pyramidKeyTap = new KeyTapGesture(gesture);
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 4;
				System.out.println("Pyramid Recognized");
				Main.canvas.display();
				shapeActivated = 0;
				scaleDistanceReset();
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
			}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Sphere Shape Creation Below
			//////////////////////////////////////////////////////////////////////////////////////
			
			else if((gesture.type() == Gesture.Type.TYPE_KEY_TAP) && (((fingersHand1.count() == 1) && (fingersHand2.count() == 5)) || ((fingersHand1.count() == 5) && (fingersHand2.count() == 1)))){
//				KeyTapGesture sphereKeyTap = new KeyTapGesture(gesture);
				undoLastAction = false;
				redoLastAction = false;
				deleteSelectedShape = false;
				shapeActivated = 5;
				System.out.println("Sphere Recognized");
				Main.canvas.display();
				shapeActivated = 0;
				scaleDistanceReset();
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
				
			}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Deletion Below NOTE: Swipe is too sensitive see UNDO/DELETE
			//////////////////////////////////////////////////////////////////////////////////////

//			else if((gesture.type() == Gesture.Type.TYPE_SWIPE)){
//				System.out.println("Delete");
//			deleteSelectedShape = true;
//        	Main.canvas.display();
//        	
//		}
			
			//////////////////////////////////////////////////////////////////////////////////////
			/////////////////Undo/Delete Below
			//////////////////////////////////////////////////////////////////////////////////////
			
			else if((gesture.type() == Gesture.Type.TYPE_CIRCLE) && (((fingersHand1.count() == 5) && (fingersHand2.count() == 0)) || ((fingersHand1.count() == 0) && (fingersHand2.count() == 5)))){
				
				CircleGesture circle = new CircleGesture(gesture);
	            // Calculate clock direction using the angle between circle normal and pointable
	            String clockwiseness;
	            if (circle.pointable().direction().angleTo(circle.normal()) <= Math.PI/4) {
	                // Clockwise if angle is less than 90 degrees
	                clockwiseness = "clockwise";
	            } else {
	                clockwiseness = "counterclockwise";
	            }

	            // Calculate angle swept since last frame
	            double sweptAngle = 0;
	            if (circle.state() != State.STATE_START) {
	                CircleGesture previousUpdate = new CircleGesture(controller.frame(1).gesture(circle.id()));
	                sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * Math.PI;
	            }
	            if((clockwiseness.equals("clockwise")) && (Math.round(circle.progress()) == 2) && (circleCheck == true)){
	            	System.out.println(circle.progress());
	            	redoLastAction = true;
	            	Main.canvas.display();
	            	circleCheck = false;
	            	System.out.println("clockwise: = " +clockwiseness + "      redo!");
	            }
	            
	            if((clockwiseness.equals("clockwise")) && (Math.round(circle.progress()) == 5) && (circleCheckDelete == true)){
	            	System.out.println(circle.progress());
	            	deleteSelectedShape = true;
	            	Main.canvas.display();
	            	circleCheckDelete = false;
	            	System.out.println("clockwise: = " +clockwiseness + "      delete!");
	            }
	            
	            if((clockwiseness.equals("counterclockwise")) && (Math.round(circle.progress()) == 2) && (circleCheck == true)){
	            	System.out.println(circle.progress());
	            	undoLastAction = true;
	            	Main.canvas.display();
	            	circleCheck = false;
	            	System.out.println("counterclockwise: = " +clockwiseness + "    undo!");
	            }
	            
			}
			

			else {
				undoLastAction = false;
				redoLastAction = false;
				scaleDistanceReset();
				translateDistanceFinalX = 0;
				translateDistanceFinalY = 0;
				translateDistanceFinalZ = 0;
				translateBoolean = false;
				shapeActivated = 0;
				deleteSelectedShape = false;
				circleCheck = true;
				circleCheckDelete = true;
				
			}
			// System.out.println("scale1: " + scaleDistance1);
			// System.out.println("scale2: " + scaleDistance2);
			// System.out.println("Final: " + scaleDistanceFinal);

			// Calculate the hand's pitch, roll, and yaw angles
			/*
			 * System.out.println("Hand pitch: " +
			 * Math.toDegrees(direction.pitch()) + " degrees, " + "roll: " +
			 * Math.toDegrees(normal.roll()) + " degrees, " + "yaw: " +
			 * Math.toDegrees(direction.yaw()) + " degrees");
			 */
		}

		

	}

}
